/**
 * @author phi
 */

(function(np){
    
    var gl = null;
    var shader_program = null;
    
    /**
     * glを初期化
     * @param {Object} canvas
     */
    np.initGL = function(canvas)
    {
        try {
            gl = canvas.getContext("experimental-webgl");
            gl.viewportWidth = canvas.width;
            gl.viewportHeight= canvas.height;
        }
        catch (e) {}
        
        if (!gl) { alert("error!!"); }
        
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.clearDepth(1.0);
        gl.enable(gl.DEPTH_TEST);
        gl.depthFunc(gl.LEQUAL);
        
        return gl;
    };
    
    
    /**
     * シェーダを取得
     * @param {Object} gl
     * @param {Object} id
     */
    var getShader = function(gl, str, type)
    {
        var shader;
        
        switch (type) {
            case "fragment" : shader = gl.createShader(gl.FRAGMENT_SHADER); break;
            case "vertex"   : shader = gl.createShader(gl.VERTEX_SHADER);   break;
            default : shader = null; break;
        }
        
        gl.shaderSource(shader, str);
        gl.compileShader(shader);
        
        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
            alert(gl.getShaderInfoLog(shader));
            return null;
        }
        
        return shader;
    };
    
    
    /**
     * シェーダを初期化
     * @param {String} vs_str 頂点シェーダ
     * @param {String} fs_str フラグメントシェーダ
     */
    np.initShaders = function(vs_str, fs_str)
    {
        shader_program  = gl.createProgram();
        
        var vertex_shader   = getShader(gl, vs_str, "vertex");
        var fragment_shader = getShader(gl, fs_str, "fragment");
        
        gl.attachShader(shader_program, vertex_shader);
        gl.attachShader(shader_program, fragment_shader);
        
        gl.linkProgram(shader_program);
        
        if (!gl.getProgramParameter(shader_program, gl.LINK_STATUS)) {
            alert("initShaders");
        }
        
        gl.useProgram(shader_program);
        
        var attr = gl.getAttribLocation(shader_program, "pos");
        gl.enableVertexAttribArray(attr);
    };
    
    /**
     * 頂点バッファを生成
     * @param {Object} gl
     * @param {Object} vertices
     */
    np.createBuffer = function()
    {
        return gl.createBuffer();
    };
    
    
    /**
     * 頂点バッファを初期化
     */
    np.initBuffer = function(buffer, vertices)
    {
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
        
        buffer.vertexNum = vertices.length/3;
    };
    
    /**
     * 描画
     * @param {Object} buffer
     * @param {Object} type
     */
    np.drawArrays = function(buffer)
    {
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
        gl.vertexAttribPointer(shader_program.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
        gl.drawArrays(gl.TRIANGLES, 0, buffer.vertexNum);
    }
    
    
    /**
     * クリア
     * @param {Object} gl
     */
    np.clearDisplay = function()
    {
        gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    }
    

})(this);

(function(np){
    
    var temp_buffer = null;
    var temp_color = null;
    var temp_matrix = null;
    
    /**
     * 描画開始
     */
    np.beginDraw = function()
    {
        temp_buffer = [];
    };
    
    /**
     * 頂点情報を記録
     */
    np.vertex3 = function(x, y, z)
    {
        temp_buffer.push(x);
        temp_buffer.push(y);
        temp_buffer.push(z);
    };
    
    /**
     * 描画終了
     */
    np.endDraw = function()
    {
        var vertex_buf = createBuffer();
        initBuffer(vertex_buf, temp_buffer);
        
        drawArrays(vertex_buf);
        
        temp_buffer = null;
    };
    
    /**
     * 四角形描画
     */
    np.drawRectangle = function(x, y, width, height)
    {
        var left    = x;
        var right   = x+width;
        var top     = y;
        var bottom  = y+height;
        
        beginDraw();
            vertex3(left, top, 0.0);
            vertex3(left, bottom, 0.0);
            vertex3(right, bottom, 0.0);
            
            vertex3(right,  bottom, 0.0);
            vertex3(right, top, 0.0);
            vertex3(left, top, 0.0);
        endDraw();
    }
    
})(this);


